package com.thz.houserental.domain.reservation;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.thz.houserental.domain.house.HouseService;
import com.thz.houserental.infrastructure.auth.AuthUtil;
import com.thz.houserental.infrastructure.exception.ForbiddenException;
import com.thz.houserental.infrastructure.table.User;
import com.thz.houserental.infrastructure.web.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
/**
 * 1. 可先添加喜欢在添加收藏
 * 2. 可直接添加收藏
 * 所以收藏接口要处理两种情形。
 */
public class ReservationServiceImpl
        extends ServiceImpl<ReservationMapper, Reservation>
        implements ReservationService {
    private final UserService userService;
    private final HouseService houseService;

    public ReservationServiceImpl(@Lazy UserService userService, @Lazy HouseService houseService) {
        this.userService = userService;
        this.houseService = houseService;
    }

    @Override
    public Reservation addReservation(String houseId) {
        //TODO 删除房源的时候 reservation依旧存在
        String userId = AuthUtil.getCurrentUserId();
        Reservation reservation = Reservation.builder()
                .houseId(houseId)
                .userId(userId)
                .build();
        // 不能重复添加，先检验是否已存在
        if (isExist(userId, houseId)) {
            throw new ForbiddenException(10400);
        } else {
            this.save(reservation);
            return reservation;
        }
    }

    @Override
    public void collect(String houseId) {
        //检查reservation是否存在, 同一用户不能有第二个
        //存在有两种可能，1.已添加喜欢 2.已添加收藏。统一抛出异常
        String currentUserId = AuthUtil.getCurrentUserId();
        Reservation reservation = this.lambdaQuery()
                .eq(Reservation::getHouseId, houseId)
                .eq(Reservation::getUserId, currentUserId)
                .one();
        if (reservation != null) {
            //是喜欢
            if (reservation.getIsCollect() == null || reservation.getIsCollect() == 0) {
                reservation.setIsCollect(1);
                this.baseMapper.updateById(reservation);
            } else {
                //已收藏
                throw new ForbiddenException(10400);
            }
        } else {
            // 直接添加收藏
            Reservation build = Reservation.builder()
                    .isCollect(1)
                    .houseId(houseId)
                    .userId(AuthUtil.getCurrentUserId())
                    .build();
            this.saveOrUpdate(build);
        }
    }

    @Override
    public Page<ReservationVo> getUserAllReservation(String userId, Page<ReservationVo> reservationPage) {
        if (StrUtil.isNotEmpty(userId)) {
            //TODO 检查登录用户身份
            //TODO 检查用户是否存在
        } else {
            userId = AuthUtil.getCurrentUserId();
        }
        QueryWrapper<Reservation> reservationQueryWrapper = new QueryWrapper<>();
        reservationQueryWrapper.lambda().eq(Reservation::getUserId, userId);

        Page<ReservationVo> reservationVoPage = this.baseMapper.queryPage(reservationPage, reservationQueryWrapper);
        reservationVoPage.getRecords().forEach(e -> {
            e.setHouseVo(houseService.getDetail(e.getHouseId()));
        });
        return reservationVoPage;
    }

    @Override
    public Page<ReservationVo> getAll(QueryWrapper<Reservation> queryWrapper, Page<ReservationVo> reservationPage) {
        return this.baseMapper.queryPage(reservationPage, queryWrapper);
    }

    @Override
    public List<User> getLikedUsers(String houseId) {
        List<Reservation> reservations = this.lambdaQuery()
                .eq(Reservation::getHouseId, houseId)
                .list();

        return reservations.stream().map(e -> {
            String userId = e.getUserId();
            return userService.getById(userId);
        }).collect(Collectors.toList());
    }

    @Override
    public List<User> getCollectUsers(String houseId) {
        List<Reservation> reservations = this.lambdaQuery()
                .eq(Reservation::getHouseId, houseId)
                .eq(Reservation::getIsCollect, 1)
                .list();

        return reservations.stream().map(e -> {
            String userId = e.getUserId();
            return userService.getById(userId);
        }).collect(Collectors.toList());
    }

    @Override
    public Page<ReservationVo> getAllReservationPage(Page<ReservationVo> reservationVoPage, ReservationVo reservationVo) {
        return this.baseMapper.getAllReservationPage(reservationVoPage, reservationVo);
    }

    private boolean isExist(String userId, String houseId) {
        List<Reservation> list = this.lambdaQuery()
                .eq(Reservation::getUserId, userId)
                .eq(Reservation::getHouseId, houseId)
                .list();
        return list != null && list.size() > 0;
    }
}
